<?php
/* 
 * Copyright (c) 2018-2021   All rights reserved.
 * 
 * 创建时间：2021-08-27 12:40
 *
 * 项目：rm  -  $  - Jsapi.php
 *
 * 作者：liwei 
 */

namespace modules\levpays\sdk\wechatpay\jsapi;

use Lev;
use lev\base\Controllerv;
use lev\base\Requestv;
use lev\helpers\curlHelper;
use modules\levpays\helpers\levpaysSetHelper;
use modules\levpays\sdk\wechatpay\InstancePay;
use modules\levpays\table\tradesHelper;
use modules\levpays\table\UsersHelper;

!defined('INLEV') && exit('Access Denied LEV');

class Jsapi extends InstancePay
{

    public static function tradePre($pre = '') {
        return ($pre ?: (static::isWxmini() ? 'WXMINI' : 'JSAPI')).'-'.levpaysSetHelper::tradePre();
    }

    public static function checkTradeNo($tradeNo)
    {
        $_tradeNo = parent::getOutTradeNo($tradeNo, $pre = static::tradePre('WXMINI'));
        $res = parent::checkTradeNo($_tradeNo); // TODO: Change the autogenerated stub
        if (empty($res['_paySuccess'])) {
            $_tradeNo = parent::getOutTradeNo($tradeNo, $pre = static::tradePre('JSAPI'));
            $res = parent::checkTradeNo($_tradeNo);
        }
        $res['_tradePre'] = $pre;
        return $res;
    }

    /**
     * @param $tradeNo
     * @param $desc
     * @param $money
     * @param string $pre JSAPI WXMINI
     * @return mixed
     */
    public static function PlaceOrder($tradeNo, $desc, $money, $pre = '', $appid = '') {
        $instance = static::init();
        if (!$instance) return '';
        static::$config['_tradeId'] = tradesHelper::tradeNoToId($tradeNo);
        $pre = static::tradePre($pre);
        try {
            $resp = $instance->v3->pay->transactions->jsapi
                ->post(['json' => [
                    'mchid'        => static::$config['mchid'],
                    'out_trade_no' => InstancePay::getOutTradeNo($tradeNo, $pre),
                    'appid'        => $appid ?: static::$config['appid'],
                    'description'  => $desc, //'Image形象店-深圳腾大-QQ公仔',
                    //'notify_url'   => Lev::toReRoute(['default/notify-native']),
                    'notify_url'   => InstancePay::notifyUrl(),
                    'amount'       => [
                        'total'    => $money * 100,//单位：分
                        'currency' => 'CNY'
                    ],
                    'payer'        => [
                        'openid'   => static::getOpenid(),
                    ],
                ]]);
        } catch (\Exception $e) {
            // 进行错误处理
            //echo $e->getMessage(), PHP_EOL;
            if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
                $resp = $e->getResponse();
            }
            //echo $e->getTraceAsString(), PHP_EOL;
        }
        $res = json_decode($resp->getBody(), true);//print_r(InstancePay::getOutTradeNo($tradeNo, $pre));print_r($res);exit;
        if (empty($res['prepay_id'])) {
            Lev::setNotices($res['code'].'：'.$res['message']);
            InstancePay::paySuccess($res, $tradeNo, $pre);
            return '';
        }
        tradesHelper::setTradePaysource($tradeNo, $pre);
        return $res['prepay_id'];
    }

    public static function getOpenid()
    {
        //return static::getAccessToken(Lev::GPv('code'));
        return //UsersHelper::getWxopenid(Lev::$app['uid']) ?:
            (Lev::GPv('openid') ?: static::getAccessToken(Lev::GPv('code')));
    }

    public static function getAuthurl()
    {
        static::$config['_state']   = md5(Lev::$app['timestamp'].'-'.Lev::$app['ip'].'-'.mt_rand(123456789, 987654321));
        static::$config['scope']    = 'snsapi_base';//snsapi_login,snsapi_base,snsapi_userinfo
        static::$config['callback'] = static::$config['_tradeId'] ? Lev::toReRoute(['pay', 'tradeId'=>static::$config['_tradeId']]) : Lev::$app['referer'];//Requestv::getHostInfo().$_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING'];
        $url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.static::$config['appid'].'&redirect_uri='.urlencode(static::$config['callback']).'&response_type=code&scope='.static::$config['scope'].'&state='.static::$config['_state'].'#wechat_redirect';
        return $url;
    }

    /**
     * 正确的返回：

    {
    "access_token":"ACCESS_TOKEN",
    "expires_in":7200,
    "refresh_token":"REFRESH_TOKEN",
    "openid":"OPENID",
    "scope":"SCOPE"
    }

     * https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
     * @param $code
     *
     */
    public static function getAccessToken($code)
    {
        if (!$code) {
            $url = static::getAuthurl();
            if (Lev::isAjax()) {
                echo json_encode(Lev::responseMsg(1, '授权code', ['authurl'=>$url, $_GET, $_POST]));
                exit;
            }else {
                Controllerv::redirect($url);
            }
            return '';
        }
        static::$config['_code'] = $code;
        $pm['url'] = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.static::$config['appid'].'&secret='.static::$config['appsecret'].'&code='.$code.'&grant_type=authorization_code';
        $result = curlHelper::doCurl($pm);
        $result = json_decode($result, true);

        if ($result['errcode'] == 40163) {
            return Lev::opCookies('wxopenid');
        }

        if (!empty($result['openid'])) {
            UsersHelper::setWxopenid(Lev::$app['uid'], $result['openid']);
            Lev::opCookies('wxopenid', $result['openid'], 3600*24);
        }

        return $result['openid'];
    }
}